<?php

namespace PhpYes;

/**
 * Kpp
 *
 * Core
 * Kernel
 * Starter
 * Ini
 *
 * Yes
 *
 */
final class Yes
{
    const OK = 'ok';

    /**
     * @var null|\PhpYes\Apps\BaseApp
     */
    public static $p = null;

    /**
     * 设计用于 Controller 向 view 传递数据
     *
     * 属于一种全局类型的变量，一旦改变，全局就都改变了，
     * 多 Render 或 多 渲染组件(例如将渲染 html 的 button 或 input 或 select 的逻辑封装成一个php的 类 或者 函数) 的情况下，使用需要注意
     *
     * 可以 等于 也可以 不等于 Render 中的 data，主要取决于在 view 中使用是否方便，
     * 在 view 中使用 Render 的 data 时，有时感觉不是很方便，所以就设计了这么一个全局类型的变量，
     * 旨在向用户提供 Render data 之外的 另一种 向 view 传递数据方法，
     * 用户觉得那种方法方便就选用那种方法，或者同时都使用也是可以的。
     * 例如: Yes::$v = array(); Render->setData(Yes::$v)->display('/path/to/page.html.php');
     * 那么 Yes::$v 等于 Render 中的 data，在 page.html.php 中使用 Yes::$v 或 $this->data 都一样，没啥区别
     *
     * @var null|mixed
     */
    public static $v = null;

    /**
     * !!! 请注意维护好 KEY 的一致性，避免发生 KEY 冲突事件，最好是在一个统一的地方注册 KEY，
     * !!! 例如 在 BaseApp 类体系结构中(即包括 BaseApp 的子类) 定义 final const 类型的 1级 KEY,
     * !!! final prevents child classes from overriding constant,
     * !!! 设计 $kv 是可以存放 多级 数据的，例如 $kv[Logger][ConsoleLogger], $kv[Logger][FileLogger], $kv[Logger][SyslogLogger],
     * !!! Logger 就是 1级 KEY, 定义 BaseApp 类体系结构中，ConsoleLogger, FileLogger, SyslogLogger 可以定义在 Logger 类体系结构中.
     *
     * 定义为 public 是为了灵活方便, 但这里定义为 public 又不符合良好的程序设计,
     * 在我的程序设计生涯中, 经常会遇到 private 带来不方便的时候, 这时就需要重新设计程序来处理这种情况,
     * 当然, 重新设计程序, 可以达到即满足业务逻辑需求, 也能保证程序设计良好,
     * 但这样一来就会多消耗时间, 业务需求有时候又比较急.
     * 当然, 如果一直不去好好设计程序, 也会导致程序混乱, 维护困难, 也会增加业务需求开发的时间.
     * 我这里 定义为 public 只是为了灵活方便, 给业务需求提供一个灵活方便的可能, 而不堵死,
     * 但我肯定提倡良好的程序设计, 反对程序设计混乱,
     * 不过程序是为业务服务的, 也不能为了程序设计而设计, 过度设计, 浪费时间.
     * 给业务需求提供一个灵活方便的可能 在关键时候是特别有用的,
     * 不过如果这样一来导致了程序混乱, 那么还是需要事后整理一下程序, 重新好好设计一下.
     * 这里 定义为 public 也是修改多次后的结果, public 改成 private, private 改成 public.
     * 这次就定下来, public, 习惯一下, 不纠结了
     * @var array
     */
    public static $kv = array();

    // public static $config = array(); // 已经移至 BaseConfigApp 中去了

    private static $singles = array();

    /**
     * @param string $class - 类名
     * @return null|object
     */
    public static function getSingle($class)
    {
        $class = empty($class) ? null : trim(strval($class));
        if (empty($class)) {
            return null;
        }

        if (empty(self::$singles[$class])) {
            self::$singles[$class] = new $class();
        }

        return self::$singles[$class];
    }

}
